import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from datetime import datetime

class FileExplorer:
    def __init__(self, root):
        self.root = root
        self.root.title("文件浏览器")
        self.root.geometry("800x600")
        self.root.minsize(600, 400)

        # 设置中文字体
        self.style = ttk.Style()
        self.style.configure("Treeview.Heading", font=("SimHei", 10, "bold"))
        self.style.configure("Treeview", font=("SimHei", 10))

        # 创建主框架
        self.main_frame = ttk.Frame(root, padding="10")
        self.main_frame.pack(fill=tk.BOTH, expand=True)

        # 目录选择区域
        self.dir_frame = ttk.Frame(self.main_frame)
        self.dir_frame.pack(fill=tk.X, pady=(0, 10))

        self.dir_path_var = tk.StringVar(value=os.getcwd())
        self.dir_entry = ttk.Entry(self.dir_frame, textvariable=self.dir_path_var, width=50)
        self.dir_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))

        self.browse_btn = ttk.Button(self.dir_frame, text="浏览...", command=self.browse_directory)
        self.browse_btn.pack(side=tk.LEFT, padx=5)

        self.refresh_btn = ttk.Button(self.dir_frame, text="刷新", command=self.refresh_file_list)
        self.refresh_btn.pack(side=tk.LEFT)

        # 文件列表区域
        self.file_frame = ttk.LabelFrame(self.main_frame, text="文件列表")
        self.file_frame.pack(fill=tk.BOTH, expand=True)

        # 创建文件列表树视图
        columns = ("name", "type", "size", "modified")
        self.file_tree = ttk.Treeview(self.file_frame, columns=columns, show="headings")

        # 设置列宽和标题
        self.file_tree.column("name", width=300, anchor=tk.W)
        self.file_tree.column("type", width=100, anchor=tk.CENTER)
        self.file_tree.column("size", width=100, anchor=tk.E)
        self.file_tree.column("modified", width=180, anchor=tk.CENTER)

        self.file_tree.heading("name", text="文件名")
        self.file_tree.heading("type", text="类型")
        self.file_tree.heading("size", text="大小 (字节)")
        self.file_tree.heading("modified", text="修改时间")

        # 添加滚动条
        y_scroll = ttk.Scrollbar(self.file_frame, orient=tk.VERTICAL, command=self.file_tree.yview)
        x_scroll = ttk.Scrollbar(self.file_frame, orient=tk.HORIZONTAL, command=self.file_tree.xview)
        self.file_tree.configure(yscrollcommand=y_scroll.set, xscrollcommand=x_scroll.set)

        y_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        x_scroll.pack(side=tk.BOTTOM, fill=tk.X)
        self.file_tree.pack(fill=tk.BOTH, expand=True)

        # 绑定双击事件打开文件/目录
        self.file_tree.bind("<Double-1>", self.on_double_click)

        # 文件信息区域
        self.info_frame = ttk.LabelFrame(self.main_frame, text="文件信息")
        self.info_frame.pack(fill=tk.X, pady=(10, 0))

        self.info_text = tk.Text(self.info_frame, height=5, wrap=tk.WORD)
        self.info_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        self.info_text.config(state=tk.DISABLED)

        # 底部按钮区域
        self.btn_frame = ttk.Frame(self.main_frame)
        self.btn_frame.pack(fill=tk.X, pady=(10, 0))

        self.open_btn = ttk.Button(self.btn_frame, text="打开选中", command=self.open_selected)
        self.open_btn.pack(side=tk.LEFT, padx=5)

        self.exit_btn = ttk.Button(self.btn_frame, text="退出", command=root.quit)
        self.exit_btn.pack(side=tk.RIGHT, padx=5)

        # 刷新文件列表
        self.refresh_file_list()

    def browse_directory(self):
        """浏览并选择目录"""
        directory = filedialog.askdirectory(title="选择目录")
        if directory:
            self.dir_path_var.set(directory)
            self.refresh_file_list()

    def refresh_file_list(self):
        """刷新文件列表"""
        directory = self.dir_path_var.get()

        # 清空现有列表
        for item in self.file_tree.get_children():
            self.file_tree.delete(item)

        # 清空文件信息
        self.info_text.config(state=tk.NORMAL)
        self.info_text.delete(1.0, tk.END)
        self.info_text.config(state=tk.DISABLED)

        try:
            # 获取目录内容
            with os.scandir(directory) as entries:
                # 先显示目录
                for entry in sorted(entries, key=lambda e: (not e.is_dir(), e.name.lower())):
                    try:
                        if entry.is_dir(follow_symlinks=False):
                            self.file_tree.insert("", tk.END, values=(
                                entry.name, "目录", "-", 
                                datetime.fromtimestamp(entry.stat(follow_symlinks=False).st_mtime).strftime("%Y-%m-%d %H:%M:%S")
                            ))
                        else:
                            stat_info = entry.stat(follow_symlinks=False)
                            self.file_tree.insert("", tk.END, values=(
                                entry.name, os.path.splitext(entry.name)[1] or "文件", stat_info.st_size,
                                datetime.fromtimestamp(stat_info.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
                            ))
                    except (PermissionError, FileNotFoundError) as e:
                        # 跳过无权限或不存在的文件
                        continue
        except Exception as e:
            messagebox.showerror("错误", f"无法读取目录: {str(e)}")

    def on_double_click(self, event):
        """双击事件处理"""
        item = self.file_tree.selection()[0] if self.file_tree.selection() else None
        if item:
            file_name = self.file_tree.item(item, "values")[0]
            file_path = os.path.join(self.dir_path_var.get(), file_name)

            if os.path.isdir(file_path):
                self.dir_path_var.set(file_path)
                self.refresh_file_list()
            else:
                self.show_file_info(file_path)

    def show_file_info(self, file_path):
        """显示文件详细信息"""
        try:
            stat_info = os.stat(file_path)
            info = [
                f"文件路径: {file_path}",
                f"文件大小: {stat_info.st_size} 字节",
                f"创建时间: {datetime.fromtimestamp(stat_info.st_ctime).strftime('%Y-%m-%d %H:%M:%S')}",
                f"修改时间: {datetime.fromtimestamp(stat_info.st_mtime).strftime('%Y-%m-%d %H:%M:%S')}",
                f"访问时间: {datetime.fromtimestamp(stat_info.st_atime).strftime('%Y-%m-%d %H:%M:%S')}",
                f"文件权限: {oct(stat_info.st_mode & 0o777)}"
            ]

            self.info_text.config(state=tk.NORMAL)
            self.info_text.delete(1.0, tk.END)
            self.info_text.insert(tk.END, "\n".join(info))
            self.info_text.config(state=tk.DISABLED)
        except Exception as e:
            messagebox.showerror("错误", f"无法获取文件信息: {str(e)}")

    def open_selected(self):
        """打开选中的文件或目录"""
        item = self.file_tree.selection()[0] if self.file_tree.selection() else None
        if item:
            file_name = self.file_tree.item(item, "values")[0]
            file_path = os.path.join(self.dir_path_var.get(), file_name)

            if os.path.isdir(file_path):
                self.dir_path_var.set(file_path)
                self.refresh_file_list()
            else:
                try:
                    # 在Windows上使用start命令打开文件
                    os.startfile(file_path)
                except Exception as e:
                    messagebox.showerror("错误", f"无法打开文件: {str(e)}")

def main():
    root = tk.Tk()
    app = FileExplorer(root)
    root.mainloop()

if __name__ == "__main__":
    main()